package com.uinnova.product.eam.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.binary.core.exception.BinaryException;
import com.binary.core.util.BinaryUtils;
import com.binary.framework.exception.ServiceException;
import com.binary.jdbc.Page;
import com.uinnova.product.eam.base.exception.ServerException;
import com.uinnova.product.eam.base.model.FileResourceMeta;
import com.uinnova.product.eam.base.util.EamUtil;
import com.uinnova.product.eam.base.util.ExcelUtil;
import com.uinnova.product.eam.comm.model.es.*;
import com.uinnova.product.eam.model.*;
import com.uinnova.product.eam.model.cj.domain.PlanArtifact;
import com.uinnova.product.eam.model.dto.*;
import com.uinnova.product.eam.model.enums.ArtifactType;
import com.uinnova.product.eam.model.vo.ArtifactVo;
import com.uinnova.product.eam.model.vo.CiClassRltVo;
import com.uinnova.product.eam.model.vo.DefaultFileVo;
import com.uinnova.product.eam.model.vo.EamArtifactVoCrush;
import com.uinnova.product.eam.service.IBmHierarchySvc;
import com.uinnova.product.eam.service.IBmMultiModelHierarchySvc;
import com.uinnova.product.eam.service.IEamArtifactColumnSvc;
import com.uinnova.product.eam.service.IEamArtifactSvc;
import com.uinnova.product.eam.service.asset.BmConfigSvc;
import com.uinnova.product.eam.service.cj.service.PlanArtifactService;
import com.uinnova.product.eam.service.cj.service.PlanTemplateChapterService;
import com.uinnova.product.eam.service.es.EamArtifactDao;
import com.uinnova.product.eam.service.resource.IEamResourceSvc;
import com.uinnova.product.vmdb.comm.model.ci.CCcCiClass;
import com.uinnova.product.vmdb.comm.model.ci.CcCiClass;
import com.uinnova.product.vmdb.comm.model.image.CCcImage;
import com.uinnova.product.vmdb.provider.ci.bean.CcCiClassInfo;
import com.uinnova.project.api.diagram.v2.client.ESDiagramApiClient;
import com.uinnova.project.base.diagram.comm.model.ESDiagram;
import com.uino.api.client.cmdb.local.ImageApiSvcLocal;
import com.uino.api.client.permission.IUserApiSvc;
import com.uino.bean.cmdb.base.CcImage;
import com.uino.bean.cmdb.base.ESCIClassInfo;
import com.uino.bean.cmdb.query.ESSearchImageBean;
import com.uino.bean.permission.base.SysRole;
import com.uino.bean.permission.base.SysUser;
import com.uino.bean.permission.query.CSysUser;
import com.uino.bean.sys.base.ESDictionaryItemInfo;
import com.uino.bean.sys.query.ESDictionaryItemSearchBean;
import com.uino.dao.util.ESUtil;
import com.uino.service.cmdb.microservice.IRltClassSvc;
import com.uino.service.cmdb.microservice.impl.CIClassSvc;
import com.uino.service.permission.microservice.impl.RoleSvc;
import com.uino.service.sys.microservice.IDictionarySvc;
import com.uino.util.rsm.RsmUtils;
import com.uino.util.sys.SysUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

/**
 * @author Administrator
 */
@Slf4j
@Service
public class EamArtifactSvcImpl implements IEamArtifactSvc {

    private static final int START_NUM = 2;
    private static final int END_NUM = 100;
    private static final String ARTIFACT_NAME_KEYWORD = "artifactName.keyword";
    private static final String MESSAGE = "制品文件生成失败:{}";
    private static final String DICT_NAME = "制品类型分类";

    @Value("${http.resource.space}")
    private String rsmSlaveRoot;
    @Value("${local.resource.space}")
    private String localPath;
    @Resource
    private EamArtifactDao eamArtifactDao;
    @Autowired
    private IDictionarySvc dictSvc;
    @Resource
    private IEamArtifactColumnSvc columnSvc;
    @Resource
    private IEamResourceSvc eamResourceSvc;
    @Resource
    private ImageApiSvcLocal iImageApiSvc;
    @Resource
    private CIClassSvc clsSvc;
    @Resource
    private IRltClassSvc rltClassSvc;
    @Resource
    private BmConfigSvc bmConfigSvc;
    @Resource
    private IBmHierarchySvc hierarchySvc;
    @Resource
    private IBmMultiModelHierarchySvc modelHierarchySvc;
    @Resource
    private PlanTemplateChapterService planTemplateChapterService;
    @Resource
    private PlanArtifactService planArtifactService;
    @Autowired
    private RsmUtils rsmUtils;
    @Autowired
    private RoleSvc roleSvc;
    @Resource
    private ESDiagramApiClient diagramApiClient;
    @Resource
    private IUserApiSvc userApiSvc;

    @Override
    public Long saveOrUpdate(EamArtifactCdt cdt) {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.termQuery(ARTIFACT_NAME_KEYWORD, cdt.getArtifactName().trim()));
        boolQueryBuilder.must(QueryBuilders.termQuery("dataStatus", 1));
        if (!BinaryUtils.isEmpty(cdt.getId())) {
            boolQueryBuilder.mustNot(QueryBuilders.termQuery("id", cdt.getId()));
        }
        EamArtifact record = eamArtifactDao.selectOne(boolQueryBuilder);
        if (!BinaryUtils.isEmpty(record)) {
            throw new ServerException("制品类型名称已存在");
        }
        record = EamUtil.copy(cdt, EamArtifact.class);
        if (BinaryUtils.isEmpty(cdt.getId())) {
            record.setId(ESUtil.getUUID());
            //数据状态 1 表示正常
            record.setDataStatus(1);
            //添加的时候默认是未发布状态 0
            record.setReleaseState(0);
            record.setCreateTime(BinaryUtils.getNumberDateTime());
        }
        record.setModifyTime(BinaryUtils.getNumberDateTime());
        String loginCode = SysUtil.getCurrentUserInfo().getLoginCode();
        if(BinaryUtils.isEmpty(cdt.getId())){
            record.setCreator(loginCode);
        }
        record.setModifier(loginCode);
        return eamArtifactDao.saveOrUpdate(record);
    }

    @Override
    public Page<EamArtifactVo> queryArtifactList(ElementConditionDto dto) {
        SysUser userInfo = SysUtil.getCurrentUserInfo();
        Map<String, String> artifactDictMap = getArtifactTypeDictMap();
        Integer typeClassification = dto.getTypeClassification();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.termQuery("dataStatus", 1));
        if (!BinaryUtils.isEmpty(dto.getName())) {
            List<SysUser> userLike = userApiSvc.getUserInfoByName(dto.getName().trim());
            BoolQueryBuilder shouldQuery = QueryBuilders.boolQuery();
            if(!CollectionUtils.isEmpty(userLike)){
                Set<String> nameLists = userLike.stream().map(SysUser::getLoginCode).collect(Collectors.toSet());
                shouldQuery.should(QueryBuilders.termsQuery("creator.keyword", nameLists));
            }
            shouldQuery.should(QueryBuilders.wildcardQuery("creator.keyword", "*" + dto.getName().trim() + "*"));
            shouldQuery.should(QueryBuilders.wildcardQuery(ARTIFACT_NAME_KEYWORD, "*" + dto.getName().trim() + "*"));
            boolQueryBuilder.must(shouldQuery);
        }
        if (!BinaryUtils.isEmpty(typeClassification)) {
            boolQueryBuilder.must(QueryBuilders.termQuery("typeClassification", typeClassification));
        }
        if (!BinaryUtils.isEmpty(dto.getReleaseState())) {
            boolQueryBuilder.must(QueryBuilders.termQuery("releaseState", dto.getReleaseState()));
        }
        if (!BinaryUtils.isEmpty(dto.getTag())) {
            boolQueryBuilder.must(QueryBuilders.termQuery("typeTag.keyword", dto.getTag()));
        }
        List<SortBuilder<?>> sorts = new ArrayList<>();
        sorts.add(SortBuilders.fieldSort("modifyTime").order(SortOrder.DESC));
        Page<EamArtifact> artifactPage = eamArtifactDao.getSortListByQuery(dto.getPageNum(), dto.getPageSize(), boolQueryBuilder, sorts);
        List<EamArtifact> artifactList = artifactPage.getData();
        if (BinaryUtils.isEmpty(artifactList)) {
            return new Page<>(dto.getPageNum(), dto.getPageSize(), 0, 0, new ArrayList<>());
        }
        List<Long> picIds = artifactList.stream().filter(e -> !BinaryUtils.isEmpty(e.getFileIds())).map(e -> e.getFileIds().get(0)).collect(Collectors.toList());
        List<FileResourceMeta> download = eamResourceSvc.download(picIds);
        Map<Long, String> picMap = download.stream().collect(Collectors.toMap(FileResourceMeta::getId, FileResourceMeta::getResPath, (k1, k2) -> k2));

        List<Long> artifactIds = artifactList.stream().map(EamArtifact::getId).collect(Collectors.toList());
        List<ESDiagram> diagramList = diagramApiClient.queryByArtifactIds(artifactIds);
        Map<String, List<ESDiagram>> diagramMap = diagramList.stream().collect(Collectors.groupingBy(ESDiagram::getViewType));
        //查询一下user信息
        List<String> loginCodes = artifactList.stream().map(EamArtifact::getCreator).filter(Objects::nonNull).distinct().collect(Collectors.toList());
        Map<String, SysUser> userMap = this.queryUserMap(loginCodes);
        List<EamArtifactVo> list = new ArrayList<>();
        for (EamArtifact artifact : artifactList) {
            if (BinaryUtils.isEmpty(artifact.getCreator())) {
                artifact.setCreator(artifact.getModifier());
            }
            String dictName = artifactDictMap.get(artifact.getTypeClassification().toString());
            List<ESDiagram> diagrams = diagramMap.getOrDefault(artifact.getId().toString(), Collections.emptyList());
            artifact.setUsageCounter(diagrams.size());

            EamArtifactVo vo = EamUtil.copy(artifact, EamArtifactVo.class);
            SysUser user = userMap.get(artifact.getCreator());
            vo.setCreatorName(user == null?artifact.getCreator():user.getUserName());
            vo.setArtifactTypeName(dictName);
            if (!CollectionUtils.isEmpty(artifact.getFileIds())) {
                vo.setResPath(picMap.get(artifact.getFileIds().get(0)));
            }
            //存入图片路径
            list.add(vo);
        }
        //若前端传业务类型参数，则将该类型数据前置
        if (!BinaryUtils.isEmpty(list) && !BinaryUtils.isEmpty(typeClassification)) {
            list = list.stream().sorted(Comparator.comparing(each -> !each.getTypeClassification().equals(typeClassification))).collect(Collectors.toList());
        }
        return new Page<>(artifactPage.getPageNum(), artifactPage.getPageSize(), artifactPage.getTotalRows(), artifactPage.getTotalPages(), list);
    }

    /**
     * 查看当前用户权限，是admin=true;非admin=false;
     */
    public Boolean userRights(Long userId){
        List<SysRole> rolesByUserId = roleSvc.getRolesByUserId(userId);
        List<SysRole> adminRole =null;
        if(!BinaryUtils.isEmpty(rolesByUserId)){
            adminRole = rolesByUserId.stream().filter(each -> "admin".equals(each.getRoleName())).collect(Collectors.toList());
        }
        return !BinaryUtils.isEmpty(adminRole);
    }

    private Map<String, String> getArtifactTypeDictMap() {
        SysUser currentUserInfo = SysUtil.getCurrentUserInfo();
        ESDictionaryItemSearchBean bean = new ESDictionaryItemSearchBean();
        bean.setDomainId(currentUserInfo.getDomainId());
        bean.setDictName(DICT_NAME);
        List<ESDictionaryItemInfo> dictionaryItems = dictSvc.searchDictItemListByBean(bean);
        if(BinaryUtils.isEmpty(dictionaryItems)){
            throw new BinaryException("未查询到[制品类型分类]字典表数据，请联系管理员");
        }
        return dictionaryItems.stream().collect(Collectors.toMap(each -> each.getAttrs().get("ID"), each -> each.getAttrs().get("名称")));
    }

    @Override
    public List<EamArtifactVo> queryByType(List<Integer> type) {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.termQuery("dataStatus", 1));
//        boolQueryBuilder.must(QueryBuilders.termQuery("releaseState", 1));
        if (!BinaryUtils.isEmpty(type)) {
            boolQueryBuilder.must(QueryBuilders.termsQuery("typeClassification", type));
        }
        List<EamArtifact> artifactList = eamArtifactDao.getListByQuery(boolQueryBuilder);
        if(BinaryUtils.isEmpty(artifactList)){
            return Collections.emptyList();
        }
        return EamUtil.copy(artifactList, EamArtifactVo.class);
    }


    @Override
    public Map<String, Long> queryAllElements() {
        CEamArtifact cEamArtifact = new CEamArtifact();
        cEamArtifact.setDataStatus(1);
        List<EamArtifact> listByCdt = eamArtifactDao.getListByCdt(cEamArtifact);
        List<String> elements = listByCdt.stream().map(EamArtifact::getTypeTag)
                .filter(each -> !CollectionUtils.isEmpty(each))
                .flatMap(Collection::stream).collect(Collectors.toList());
        return elements.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
    }

    @Override
    public EamArtifactVo queryArtifact(Long artifactId) {
        Map<String, String> artifactDictMap = getArtifactTypeDictMap();
        EamArtifact artifact = this.getArtifactId(artifactId, 1);
        if (artifact == null) {
            return null;
        }
        if (artifact.getIsSupportDragAsset() == null) {
            artifact.setIsSupportDragAsset(Boolean.FALSE);
        }
        EamArtifactVo vo = EamUtil.copy(artifact, EamArtifactVo.class);
        String typeName = artifactDictMap.get(vo.getTypeClassification().toString());
        vo.setArtifactTypeName(typeName);
        if(BinaryUtils.isEmpty(vo.getCreator())){
            vo.setCreator(vo.getModifier());
        }
        if (CollectionUtils.isEmpty(artifact.getFileIds())) {
            return vo;
        }
        vo.setFileId(artifact.getFileIds().get(0));
        //只有一张图片
        List<FileResourceMeta> download = eamResourceSvc.download(artifact.getFileIds());
        if (BinaryUtils.isEmpty(download)) {
            //获取第一张默认图
            List<DefaultFileVo> defaultFileVos = defaultImage();
            vo.setResPath(defaultFileVos.get(0).getResPath());
        } else {
            vo.setResPath(download.get(0).getResPath());
        }
        return vo;
    }

    @Override
    public List<EamArtifactVo> queryArtifactByIds(List<Long> artifactIds) {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.termQuery("dataStatus", 1));
        boolQueryBuilder.must(QueryBuilders.termQuery("releaseState", 1));
        boolQueryBuilder.must(QueryBuilders.termsQuery("id", artifactIds));
        List<EamArtifact> eamArtifactList = eamArtifactDao.getListByQuery(boolQueryBuilder);
        if (CollectionUtils.isEmpty(eamArtifactList)) {
            return null;
        }
        ArrayList<EamArtifactVo> result = new ArrayList<>();
        List<DefaultFileVo> defaultImg = defaultImage();
        for (EamArtifact artifact : eamArtifactList) {
            EamArtifactVo vo = EamUtil.copy(artifact, EamArtifactVo.class);
            if (!CollectionUtils.isEmpty(artifact.getFileIds())) {
                List<FileResourceMeta> download = eamResourceSvc.download(artifact.getFileIds());
                //获取第一张默认图
                if (BinaryUtils.isEmpty(download)) {
                    vo.setFileId(defaultImg.get(0).getFileId());
                    vo.setResPath(defaultImg.get(0).getResPath());
                }else{
                    vo.setFileId(download.get(0).getId());
                    vo.setResPath(download.get(0).getResPath());
                }
            }
            result.add(vo);
        }
        return result;
    }

    @Override
    public List<DefaultFileVo> defaultImage() {
        List<DefaultFileVo> result = new ArrayList<>();
        String jsonVal = bmConfigSvc.getConfigType("DEFAULT_IMG");
        if(BinaryUtils.isEmpty(jsonVal)){
            return result;
        }
        List<FileResourceMeta> configList = JSON.parseArray(jsonVal, FileResourceMeta.class);
        List<Long> conf = configList.stream().map(FileResourceMeta::getId).collect(Collectors.toList());
        List<FileResourceMeta> download = eamResourceSvc.download(conf);
        if (!CollectionUtils.isEmpty(download)) {
            for (FileResourceMeta each : download) {
                DefaultFileVo vo = new DefaultFileVo();
                vo.setResPath(each.getResPath());
                vo.setFileId(each.getId());
                if (!BinaryUtils.isEmpty(each.getName())) {
                    vo.setImageName(each.getName().substring(0, each.getName().indexOf(".")));
                }
                vo.setDefaultImg(true);
                vo.setCreateTime(0L);
                result.add(vo);
            }
        }
        result.sort(Comparator.comparing(DefaultFileVo::getImageName));
        return result;
    }


    @Override
    public Long releaseArtifact(Long artifactId, Integer releaseState) {
        EamArtifact artifact = eamArtifactDao.getById(artifactId);
        if (!BinaryUtils.isEmpty(artifact)) {
            artifact.setReleaseState(releaseState);
        } else {
            throw new ServerException("制品信息不存在");
        }
        return eamArtifactDao.saveOrUpdate(artifact);
    }

    @Override
    public Long deleteArtifact(Long artifactId) {
        EamArtifact artifact = eamArtifactDao.getById(artifactId);
        if (!BinaryUtils.isEmpty(artifact)) {
            //数据状态[DATA_STATUS]   0=删除，1=正常
            artifact.setDataStatus(0);
        } else {
            throw new ServerException("制品信息不存在");
        }
        return eamArtifactDao.saveOrUpdate(artifact);
    }

    @Override
    public Long getIdByArtifactName(String artifactName) {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.termQuery(ARTIFACT_NAME_KEYWORD, artifactName.trim()));
        boolQueryBuilder.must(QueryBuilders.termQuery("dataStatus", 1));
        EamArtifact record = eamArtifactDao.selectOne(boolQueryBuilder);
        if (BinaryUtils.isEmpty(record)) {
            return null;
        }
        return record.getId();
    }

    @Override
    public Long copyArtifact(Long artifactId) {
        EamArtifact artifact = eamArtifactDao.getById(artifactId);
        if (0 == artifact.getDataStatus()) {
            throw new ServerException("制品不存在");
        }
        artifact.setId(ESUtil.getUUID());
        artifact.setReleaseState(0);
        artifact.setCreator(SysUtil.getCurrentUserInfo().getLoginCode());
        artifact.setCreateTime(ESUtil.getNumberDateTime());
        artifact.setModifyTime(ESUtil.getNumberDateTime());
        String artifactName = artifact.getArtifactName();
        //根据制品名称找到相应记录
        BoolQueryBuilder queryBuilder = new BoolQueryBuilder();
        String key = "-副本";
        queryBuilder.must(QueryBuilders.wildcardQuery(ARTIFACT_NAME_KEYWORD, artifactName + "*"))
                .mustNot(QueryBuilders.termQuery(ARTIFACT_NAME_KEYWORD, artifactName))
                .must(QueryBuilders.termQuery("dataStatus", 1));
        List<EamArtifact> listByQuery = eamArtifactDao.getListByQuery(queryBuilder);
        //拿到所有的artifactName
        List<String> names = listByQuery.stream().map(EamArtifact::getArtifactName).collect(Collectors.toList());
        String oldName = artifact.getArtifactName();
        if (!names.contains(artifactName + key)) {
            artifact.setArtifactName(artifactName + key);
        } else {
            Set<Integer> set = new HashSet<>(names.size());
            String prefix = oldName + key;
            Pattern pattern = Pattern.compile("(" + prefix + "\\(\\d+\\))");
            Set<String> regexSet = modelHierarchySvc.getTemplateRegexSet(names, pattern);
            //符合正则表达式的取出来遍历；
            for (String name : regexSet) {
                String s = name.substring(name.lastIndexOf("(") + 1, name.lastIndexOf(")"));
                int num = Integer.parseInt(s);
                set.add(num);
            }
            if (BinaryUtils.isEmpty(set)) {
                artifact.setArtifactName(artifactName + key + "(" + 2 + ")");
            }else{
                for (int i = START_NUM; i < END_NUM; i++) {
                    if (!set.contains(i)) {
                        artifact.setArtifactName(artifactName + key + "(" + i + ")");
                        break;
                    }
                }
            }
        }
        eamArtifactDao.saveOrUpdate(artifact);
        //保存分栏数据，更新制品id
        ElementDto dto = new ElementDto();
        dto.setArtifactId(artifactId);
        List<EamArtifactElementVo> elementVoList = columnSvc.queryAllColumns(dto);
        if (!BinaryUtils.isEmpty(elementVoList)) {
            for (EamArtifactElementVo elementVo : elementVoList) {
                elementVo.setArtifactId(artifact.getId());
                elementVo.setId(ESUtil.getUUID());
                elementVo.setCreateTime(ESUtil.getNumberDateTime());
            }
            List<EamArtifactElementDto> elements = EamUtil.copy(elementVoList, EamArtifactElementDto.class);
            ArtifactElementDto dto1 = new ArtifactElementDto();
            dto1.setElements(elements);
            columnSvc.saveOrUpdate(dto1);
        }
        return null;
    }


    @Override
    public ResponseEntity<byte[]> exportArtifact(Long artifactId) {
        //获取制品基本信息
        EamArtifact artifact = eamArtifactDao.getById(artifactId);
        if(BinaryUtils.isEmpty(artifact)){
            throw new ServerException("制品不存在,请检查");
        }
        List<File> fileList = new ArrayList<>();
        //  默认图也无差别处理，都下载
        List<FileResourceMeta> download = eamResourceSvc.download(artifact.getFileIds());
        if (!CollectionUtils.isEmpty(download)) {
            //全路径 需要截掉
            String resPath = download.get(0).getResPath();
            String path = resPath.split("rsm")[1];
            //图片在服务器中的绝对路径
            rsmUtils.downloadRsmAndUpdateLocalRsm(path);
            fileList.add(new File(localPath + path));
        }
        //查询制品分栏数据
        List<EamArtifactElementVo> elements = columnSvc.queryByArtifactId(artifactId, null);
        ArtifactVo vo = new ArtifactVo();
        vo.setArtifact(artifact);
        vo.setElements(elements);
        vo.setIdent("artifact_json");
        //待压缩文件/目录所在的目录
        File fileFolder = new File(artifact.getArtifactName() + ".json");
        try (FileOutputStream fileOutputStream = new FileOutputStream(fileFolder)) {
            IOUtils.write(JSON.toJSONString(vo), fileOutputStream, String.valueOf(StandardCharsets.UTF_8));
        } catch (IOException e) {
            log.error(MESSAGE, e.getMessage());
        }
        fileList.add(fileFolder);
        File tempFile = new File(localPath + "/temp/");
        if (!tempFile.exists()) {
            boolean mkdir = tempFile.mkdir();
        }
        //制品信息
        String time = DateTimeFormatter.ofPattern("yyyyMMddhhmmss").format(LocalDateTime.now());
        String namePath = localPath + "/temp/" + artifact.getArtifactName().replaceAll("/", "-") + time + ".zip";
        //指定压缩完成后zip文件的存储路径
        try (ZipOutputStream zipOutputStream = new ZipOutputStream(Files.newOutputStream(Paths.get(namePath)))) {
            //遍历目录下的所有文件/目录，并将它们添加到压缩文件中
            for (File file : fileList) {
                //一个ZipEntry对应压缩文件中的一项
                ZipEntry zipEntry = new ZipEntry(file.getName());
                zipOutputStream.putNextEntry(zipEntry);
                try (FileInputStream in = new FileInputStream(file)) {
                    byte[] byteArray = new byte[1024];
                    int len;
                    while ((len = in.read(byteArray)) != -1) {
                        zipOutputStream.write(byteArray, 0, len);
                    }
                } catch (IOException ex) {
                    log.error(MESSAGE, ex.getMessage());
                }finally {
                    zipOutputStream.closeEntry();
                }
            }
        } catch (IOException ex) {
            log.error(MESSAGE, ex.getMessage());
        }

        File file = new File(namePath);
        ResponseEntity<byte[]> responseEntity = ExcelUtil.returnRes(file);
        //删制品
        FileUtils.deleteQuietly(fileFolder);
        //删压缩包
        FileUtils.deleteQuietly(file);
        return responseEntity;
    }

    @Override
    public String importArtifact(File file)  {
        String jsonStr = "";
        Long picId = null;
        if(!file.getName().endsWith("zip")){
            throw new BinaryException("导入文件格式不正确");
        }
        //获得输入流，文件为.zip格式；
        try (ZipInputStream in = new ZipInputStream(Files.newInputStream(file.toPath()));
             ZipFile zipFile = new ZipFile(file, StandardCharsets.UTF_8)) {
            ZipEntry zipEntry;

            //循环读取zip中的cvs/txt文件，zip文件名不能包含中文；
            while ((zipEntry = in.getNextEntry()) != null) {
                //如果是目录，不处理；
                if (zipEntry.isDirectory()) {
                }
                String fileName = zipEntry.getName();
                boolean isJson = fileName.contains("json");
                try (InputStream inputStream = zipFile.getInputStream(zipEntry)) {
                    if (isJson) {
                        jsonStr = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
                        IOUtils.closeQuietly(inputStream);
                    } else {
                        //是图片的话，判断下环境中是够存在这张图片，存在 就直接用存在的名字
                        List<EamResource> resources = eamResourceSvc.getByName(fileName);
                        if (!BinaryUtils.isEmpty(resources)) {
                            picId = resources.get(0).getId();
                        } else {
                            Long dateTimeFolder = ESUtil.getNumberDate();
                            String fileType = fileName.substring(fileName.lastIndexOf(".") + 1);
                            String destFileName = ESUtil.getUUID() + "." + fileType;
                            String resPath = "/" + dateTimeFolder + "/" + destFileName;
                            String userName = SysUtil.getCurrentUserInfo().getUserName();
                            File file1 = new File(localPath + "/"+dateTimeFolder);
                            if(!file1.exists()){
                                file1.mkdir();
                            }
                            File resFile = new File(localPath + resPath);
                            FileOutputStream fileOutputStream = new FileOutputStream(resFile);
                            IOUtils.copy(inputStream, fileOutputStream);
                            IOUtils.closeQuietly(fileOutputStream);
                            rsmUtils.uploadRsmFromFile(resFile);

                            EamResource resource = new EamResource();
                            resource.setName(fileName);
                            resource.setOperator(userName);
                            resource.setResType(fileType);
                            resource.setResPath(resPath);
                            picId = eamResourceSvc.saveOrUpdate(resource);
                        }
                    }
                } catch (Exception e) {
                    throw new BinaryException("导入文件格式不正确");
                }
            }
        } catch (IOException e) {
            throw new BinaryException(e);
        }
        //处理json制品信息
        Long domainId = SysUtil.getCurrentUserInfo().getDomainId();
        if (BinaryUtils.isEmpty(jsonStr)) {
            throw new ServiceException("文件不能为空");
        }
        ArtifactVo artifactVo;
        try {
            artifactVo = JSON.parseObject(jsonStr, ArtifactVo.class);
        } catch (Exception e) {
            throw new ServiceException("当前导入的json数据存在异常，请检查数据");
        }
        if (BinaryUtils.isEmpty(artifactVo.getIdent()) || !"artifact_json".equals(artifactVo.getIdent())) {
            throw new ServiceException("当前导入的文件不是制品类型的文件，请重新检查");
        }
        EamArtifact artifact = artifactVo.getArtifact();
        artifact.setFileIds(Collections.singletonList(picId));
        artifact.setReleaseState(0);
        artifact.setCreateTime(BinaryUtils.getNumberDateTime());
        artifact.setModifyTime(BinaryUtils.getNumberDateTime());
        BoolQueryBuilder artifactQuery = new BoolQueryBuilder();
        if (BinaryUtils.isEmpty(artifact.getArtifactName()) || BinaryUtils.isEmpty(artifact.getTypeClassification())) {
            throw new ServiceException("当前导入的json数据存在异常，请检查数据");
        }
        artifactQuery.must(QueryBuilders.termQuery(ARTIFACT_NAME_KEYWORD, artifact.getArtifactName()))
                .must(QueryBuilders.termQuery("dataStatus", 1));
        List<EamArtifact> listByQuery = eamArtifactDao.getListByQuery(artifactQuery);
        if (!BinaryUtils.isEmpty(listByQuery)) {
            throw new BinaryException("制品已存在");
        }
        if (BinaryUtils.isEmpty(artifactVo.getElements())) {
            eamArtifactDao.saveOrUpdate(artifact);
            return null;
        }
        List<EamArtifactElementVo> elementVoList = new ArrayList<>();
        //1：校验制品中的分类信息
        List<EamArtifactElementVo> relationMinus = artifactVo.getElements().stream().filter(each -> each.getType() == ArtifactType.DISTINGUISH_TYPE.val()).collect(Collectors.toList());
        List<EamArtifactElementVo> relation1 = artifactVo.getElements().stream().filter(each -> each.getType() == ArtifactType.CI_TYPE.val()).collect(Collectors.toList());
        List<EamArtifactElementVo> relation2 = artifactVo.getElements().stream().filter(each -> each.getType() == ArtifactType.ASSET_TYPE.val()).collect(Collectors.toList());
        //type=2栏所有的架构分类
        List<EamArtifactCiVo> ciElements = relation2.stream().map(EamArtifactElementVo::getElementCiObj).flatMap(Collection::stream).collect(Collectors.toList());
        //將分类name提出來
        List<String> nameList = ciElements.stream().map(EamArtifactCiVo::getName).collect(Collectors.toList());
        String[] classNames = nameList.toArray(new String[0]);
        CCcCiClass classQuery = new CCcCiClass();
        classQuery.setDomainId(domainId);
        classQuery.setClassNames(classNames);
        //将制品里的的分类信息在新环境中分类个数对比
        List<CcCiClassInfo> ciClassList = clsSvc.queryClassByCdt(classQuery);
        List<String> classNameList = ciClassList.stream().map(each -> each.getCiClass().getClassName()).collect(Collectors.toList());
        List<String> notExistClass = new ArrayList<>() ;
        for (String className : nameList) {
            if(!classNameList.contains(className)){
                notExistClass.add(className);
                continue;
            }
        }
        if (!BinaryUtils.isEmpty(notExistClass)) {
            log.error("导入失败:新环境中的对象管理分类缺失，原环境和新环境中的对象分类数据对比【{}】",JSON.toJSONString(nameList+"&&&&"+ciClassList));
            return "对象分类"+ JSON.toJSONString(notExistClass) +"缺失，请重新确认";
        }
        Map<String, CcCiClass> classMap = ciClassList.stream().map(CcCiClassInfo::getCiClass).collect(Collectors.toMap(CcCiClass::getClassName, each -> each, (k1, k2) -> k1));
        //2：校验制品中的关系分类
        List<EamArtifactElementVo> relation3 = artifactVo.getElements().stream().filter(each -> each.getType() == ArtifactType.RLT_TYPE.val()).collect(Collectors.toList());
        //查询当前环境中所有关系
        List<CcCiClassInfo> rltInfos = rltClassSvc.queryAllClasses(domainId);
        Map<String, CcCiClass> rltMap = rltInfos.stream().map(CcCiClassInfo::getCiClass).collect(Collectors.toMap(CcCiClass::getClassName, each -> each, (k1, k2) -> k1));
        if (!BinaryUtils.isEmpty(relation3) && !BinaryUtils.isEmpty(relation3.get(0).getElements())) {
            EamArtifactElementVo elementVo = relation3.get(0);
            //校验元模型中的关系数据：获取到 制品中type=2栏中所有的 的架构元素的分类的id
            List<Long> elementCiIds = ciClassList.stream().map(each -> each.getCiClass().getId()).collect(Collectors.toList());
            List<CiClassRltVo> ciClassRltVos = columnSvc.queryRelationFromObjects(elementCiIds);
            //26  27   26 和27之间有包含关系，27 和 27之间也有包含关系，接口会返回这两个的所有关系 包括自己对自己，不能直接判断相等，根据type=3关系栏组装出一个key=源端+关系+目标端，value=关系数据 的map
            Map<String, CiClassRltVo> modelMap = ciClassRltVos.stream().collect(Collectors.toMap(each -> each.getSourceCiInfo().getClassName() + each.getRltClassInfo().getCiClass().getClassName() + each.getTargetCiInfo().getClassName(), each -> each, (k1, k2) -> k1));
            //制品中架构元素关系条数 和 新环境中的元模型数据做对比；
            Set<String> notexistRlt = new HashSet<>();
            for (EamArtifactRltVo rltVo : elementVo.getElementRltObj()){
                //关系
                VcCiClassInfo rltClassInfo = rltVo.getRltClassInfo();
                CcCiClass artifactClass = rltClassInfo.getCiClass();
                String sourceName = rltVo.getSourceCiInfo().getClassName();
                String targetName = rltVo.getTargetCiInfo().getClassName();
                String rltClassName = artifactClass.getClassName().trim();
                String key = sourceName + rltClassName + targetName;
                //判断对象分类是否存在，元模型中的关系是否存在
                if (BinaryUtils.isEmpty(rltMap.get(rltClassName)) || BinaryUtils.isEmpty(modelMap.get(key))) {
                    notexistRlt.add(rltClassName);
                    log.error("导入失败:新环境中的关系分类缺失，异常数据【{}】",JSON.toJSONString("关系名称="+rltClassName));
                }
            }
            //校验关系分类是否存在；
            if(!BinaryUtils.isEmpty(notexistRlt)){
                return "关系数据"+JSON.toJSONString(notexistRlt)+"缺失，请检查元模型管理/关系管理";
            }
            List<String> rltVoList = new ArrayList<>();
            for (EamArtifactRltVo rltVo : elementVo.getElementRltObj()) {
                //关系
                VcCiClassInfo rltClassInfo = rltVo.getRltClassInfo();
                CcCiClass artifactClass = rltClassInfo.getCiClass();
                String rltClassName = artifactClass.getClassName().trim();
                //当前环境中的关系数据
                CcCiClass nowClass = rltMap.get(rltClassName);
                //制品中
                artifactClass.setId(nowClass.getId());
                artifactClass.setIcon(nowClass.getIcon());
                artifactClass.setShape(nowClass.getShape());
                rltClassInfo.setCiClass(artifactClass);
                rltVo.setRltClassInfo(rltClassInfo);
                //源端
                ESCIClassInfo sourceCiInfo = rltVo.getSourceCiInfo();
                CcCiClass sourceCi = classMap.get(sourceCiInfo.getClassName());
                sourceCiInfo.setId(sourceCi.getId());
                sourceCiInfo.setIcon(sourceCi.getIcon());
                sourceCi.setShape(sourceCi.getShape());
                rltVo.setSourceCiInfo(sourceCiInfo);
                //目标端
                ESCIClassInfo targetCiInfo = rltVo.getTargetCiInfo();
                CcCiClass targetCi = classMap.get(targetCiInfo.getClassName());
                targetCiInfo.setId(targetCi.getId());
                targetCiInfo.setIcon(targetCi.getIcon());
                targetCiInfo.setShape(targetCi.getShape());
                rltVo.setTargetCiInfo(targetCiInfo);
                rltVoList.add(JSON.toJSONString(rltVo));
            }
            elementVo.setElements(rltVoList);
            elementVoList.add(elementVo);
        }
        List<EamArtifactElementVo> updateElementList = new ArrayList<>();
        //将制品中CI分类的id更新（type=1）
        if(!BinaryUtils.isEmpty(relation1)){
            updateElementList.addAll(relation1);
        }
        //将制品中CI分类的id更新（type=2）
        if(!BinaryUtils.isEmpty(relation2)){
            updateElementList.addAll(relation2);
        }
        //保存type=-1
        if(!BinaryUtils.isEmpty(relationMinus)){
            updateElementList.addAll(relationMinus);
        }
        if(!BinaryUtils.isEmpty(updateElementList)){
            elementVoList.addAll(refreshElementsIcon(updateElementList, classMap));
        }
        //保存制品基本信息
        Long newArtifactId = eamArtifactDao.saveOrUpdate(artifact);
        //保存制品分栏信息
        ArtifactElementDto dto1 = new ArtifactElementDto();
        if (!BinaryUtils.isEmpty(elementVoList)) {
            for (EamArtifactElementVo vo : elementVoList) {
                vo.setArtifactId(newArtifactId);
            }
        }
        List<EamArtifactElementDto> copy = EamUtil.copy(elementVoList, EamArtifactElementDto.class);
        dto1.setElements(copy);
        columnSvc.saveOrUpdate(dto1);
        return null;
    }

    private List<EamArtifactElementVo> refreshElementsIcon(List<EamArtifactElementVo> relationList, Map<String, CcCiClass> classMap) {
        //文件夹名称
        Set<String> dirNames = new HashSet<>();
        //图标名称
        Set<String> shapeNames = new HashSet<>();
        Set<String> elements = relationList.stream().map(EamArtifactElementVo::getElements).flatMap(Collection::stream).collect(Collectors.toSet());
        for (String ele : elements) {
            JSONObject productEleJson = JSON.parseObject(ele);
            if ("class".equals(productEleJson.get("type")) && !BinaryUtils.isEmpty(productEleJson.get("type"))) {
                if (!BinaryUtils.isEmpty(productEleJson.get("shape"))) {
                    String shape = productEleJson.get("shape").toString();
                    if (shape.contains("|")) {
                        dirNames.add(shape.substring(0, shape.indexOf("|")));
                        shapeNames.add(shape.substring(shape.indexOf("|") + 1));
                    } else {
                        shapeNames.add(shape);
                    }
                }
                if (!BinaryUtils.isEmpty(productEleJson.get("imgFullName"))) {
                    String imgFullName = productEleJson.get("imgFullName").toString();
                    if (imgFullName.contains("|")) {
                        dirNames.add(imgFullName.substring(0, imgFullName.indexOf("|")));
                        shapeNames.add(imgFullName.substring(imgFullName.indexOf("|") + 1));
                    } else {
                        shapeNames.add(imgFullName);
                    }
                }
            }
        }
        Page<CcImage> imagePage;
        ESSearchImageBean imageBean = new ESSearchImageBean();
        CCcImage cdt = new CCcImage();
        imageBean.setImgNames(dirNames);
        imageBean.setCdt(cdt);
        imageBean.setImgNames(shapeNames);
        imagePage = iImageApiSvc.queryImagePage(imageBean);
        Map<String, CcImage> imageMap = null;
        if (!BinaryUtils.isEmpty(imagePage.getData())) {
            //key是文件夹名称|图片名称，value是图片路径； 架构分类的shape和imgFullName字段值存入的就是图标的imageFullName字段值，故以此为map的key
            imageMap = imagePage.getData().stream().collect(Collectors.toMap(CcImage::getImgFullName, each ->each, (k1, k2) -> k1));
        }
        for (EamArtifactElementVo elementVo : relationList) {
            List<String> elementsList = elementVo.getElements();
            List<String> newElements = new ArrayList<>();
            for (String element : elementsList) {
                JSONObject eleJson = JSON.parseObject(element);
                if (!"class".equals(eleJson.get("type"))) {
                    //此处过滤的是形状，处理一下导入文件json内地址路径
                    if (StringUtils.isNotBlank(eleJson.getString("nodeData"))) {
                        JSONObject nodeData = JSON.parseObject(eleJson.getString("nodeData"));
                        String image = nodeData.getString("image");
                        if (StringUtils.isNotBlank(image) && image.startsWith("http") && image.contains("rsm")) {
                            image = image.substring(image.indexOf("/rsm") + 4);
                            nodeData.put("image", image);
                            eleJson.put("nodeData", nodeData);
                        }
                        String icon = eleJson.getString("icon");
                        if (StringUtils.isNotBlank(icon) && icon.startsWith("http") && icon.contains("rsm")) {
                            icon = icon.substring(icon.indexOf("/rsm") + 4);
                            eleJson.put("icon", icon);
                        }
                        String url = eleJson.getString("url");
                        if (StringUtils.isNotBlank(url) && url.startsWith("http") && url.contains("rsm")) {
                            url = url.substring(url.indexOf("/rsm") + 4);
                            eleJson.put("url", url);
                        }
                    }
                    newElements.add(eleJson.toJSONString());
                    continue;
                }
                CcCiClass ciClass = classMap.get(eleJson.get("name"));
                eleJson.put("id",ciClass.getId());
                Set<String> notExistShape = new HashSet<>();
                //有icon路径,有icon位置|名称
                if (!BinaryUtils.isEmpty(eleJson.get("icon")) && !BinaryUtils.isEmpty(eleJson.get("shape"))) {
                    String shape = eleJson.get("shape").toString();
                    String icon = eleJson.get("icon").toString();
                    int i = icon.indexOf("/rsm");
                    String subIcon = icon.substring(i+4);
                    String nowIcon = rsmSlaveRoot + subIcon;
                    if (!BinaryUtils.isEmpty(imageMap) && !BinaryUtils.isEmpty(imageMap.get(shape))) {
                        if (!imageMap.get(shape).equals(nowIcon)) {
                            //如果当前环境中的图标跟制品中的不匹配，会刷新环境中的icon进行展示
                            eleJson.put("icon", imageMap.get(shape));
                        } else {
                            eleJson.put("icon", nowIcon);
                        }
                    } else {
                        notExistShape.add(shape);
                        //环境中的图标没查到，这时候要取分类的默认图标；
                        String classIcon = ciClass.getIcon();
                        eleJson.put("icon", classIcon);
                        eleJson.put("shape", ciClass.getShape());
                    }

                }
                //有icon路径,无icon位置|名称，直接给定架构分类的icon路径；
                if (!BinaryUtils.isEmpty(eleJson.get("icon")) && BinaryUtils.isEmpty(eleJson.get("shape"))) {
                    String icon = eleJson.get("icon").toString();
                    String substring = icon.substring(icon.indexOf("/rsm") + 4);
                    eleJson.put("icon", rsmSlaveRoot + substring);
                }
                //viewIcon字段处理逻辑同icon，viewIcon 和 imgFullName 在更换了图标之后开始有值
                if (!BinaryUtils.isEmpty(eleJson.get("viewIcon")) && !BinaryUtils.isEmpty(eleJson.get("imgFullName")) ) {
                    String imageFullName = eleJson.get("imgFullName").toString();
                    String nowIcon = rsmSlaveRoot + eleJson.get("viewIcon");
                    if (!BinaryUtils.isEmpty(imageMap) && !BinaryUtils.isEmpty(imageMap.get(imageFullName).getImgPath())) {
                        String imgPath = imageMap.get(imageFullName).getImgPath();
                        if (!imgPath.equals(nowIcon)) {
                            //如果当前环境中的图标跟制品中的不匹配，会取环境中的icon进行展示
                            eleJson.put("viewIcon", imgPath);
                            eleJson.put("imgFullName",imageMap.get(imageFullName).getImgFullName());
                        } else {
                            eleJson.put("viewIcon", nowIcon);
                        }
                    } else {
                        notExistShape.add(imageFullName);
                        //环境中的图标没查到，这时候要取分类的默认图标；走到这个逻辑里，已经走到架构元素里了，classMap一定是非空的；
                        String classIcon = classMap.get(eleJson.get("name")).getIcon();
                        eleJson.put("viewIcon", rsmSlaveRoot + classIcon);
                        eleJson.put("viewFullName",classMap.get(eleJson.get("name")).getShape());
                    }
                }
                if(!BinaryUtils.isEmpty(eleJson.get("viewIcon")) && BinaryUtils.isEmpty(eleJson.get("imgFullName"))){
                    String viewIcon = eleJson.get("viewIcon").toString();
                    String substring = viewIcon.substring(viewIcon.indexOf("/rsm") + 4);
                    eleJson.put("viewIcon", rsmSlaveRoot + substring);
                }
                if(!BinaryUtils.isEmpty(notExistShape)){
                    log.info("导入制品接口：当前系统图标"+ JSON.toJSONString(notExistShape) +"缺失");
                }
                newElements.add(eleJson.toJSONString());
            }
            elementVo.setElements(newElements);
        }
        return relationList;
    }


    @Override
    public List<EamArtifact> queryByConditions(EamArtifact artifact) {
        CEamArtifact copy = EamUtil.copy(artifact, CEamArtifact.class);
        return eamArtifactDao.getListByCdt(copy);
    }

    @Override
    public String checkBeforeReleaseArtifact(Long artifactId) {
        //查询层级配置是否引用该制品
        List<EamMultiModelHierarchy> modelList = modelHierarchySvc.queryList(null, 1);
        List<EamHierarchyDto> hierarchyLists = hierarchySvc.queryList(null);
        if (!BinaryUtils.isEmpty(modelList) && !BinaryUtils.isEmpty(hierarchyLists)) {
            List<Long> modelIds = modelList.stream().map(EamMultiModelHierarchy::getId).collect(Collectors.toList());
            for (EamHierarchyDto each : hierarchyLists) {
                if(modelIds.contains(each.getModelId()) && artifactId.equals(each.getArtifactId())){
                    return "该制品类型已被模型树引用，请重新检查";
                }
            }
        }
        //交付物模板
        boolean deliverCheck = planTemplateChapterService.checkViewType(artifactId.toString());
        //方案
        PlanArtifact planArtifact = new PlanArtifact();
        planArtifact.setDiagramProductType(artifactId.toString());
        List<PlanArtifact> planArtifactList = planArtifactService.findPlanArtifactList(planArtifact);
        boolean planCheck = CollectionUtils.isEmpty(planArtifactList);
        if (!deliverCheck && !planCheck) {
            return "该制品类型已被交付物模板和方案引用，请重新检查";
        }
        if (!deliverCheck) {
            return "该制品类型已被交付物模板引用，请重新检查";
        }
        if (!planCheck) {
            return "该制品类型已被方案引用，请重新检查";
        }
        return null;
    }

    @Override
    public List<EamArtifact> queryArtifactListByIds(List<Long> artifactIds, Integer dataStatus) {
        BoolQueryBuilder query = new BoolQueryBuilder();
        query.must(QueryBuilders.termsQuery("id", artifactIds))
                .must(QueryBuilders.termQuery("dataStatus", dataStatus));
        return eamArtifactDao.getListByQuery(query);
    }

    @Override
    public EamArtifact getArtifactId(Long id, Integer dataStatus) {
        BoolQueryBuilder query = new BoolQueryBuilder();
        query.must(QueryBuilders.termQuery("id", id));
        query.must(QueryBuilders.termQuery("dataStatus", dataStatus));
        return eamArtifactDao.selectOne(query);
    }

    @Override
    public String crushArtifactColumns() {
        //获取所有得制品，取到制品分栏信息，，根据分类id，查到对应的classCode字段，刷进去 之后再批量保存；
        BoolQueryBuilder query = new BoolQueryBuilder();
        query.must(QueryBuilders.termQuery("dataStatus", 1));
        List<EamArtifact> queryScroll = eamArtifactDao.getListByQueryScroll(query);
        if (BinaryUtils.isEmpty(queryScroll)) {
            return "制品存量数据已更新";
        }
        List<Long> artifactIds = queryScroll.stream().map(EamArtifact::getId).collect(Collectors.toList());
        Map<Long, List<EamArtifactElementVo>> columnsByIdsMap = columnSvc.queryAllColumnsByIds(artifactIds);
        //查询所有分类
        List<CcCiClassInfo> classList = clsSvc.queryClassByCdt(new CCcCiClass());
        Map<String, CcCiClass> classMap = classList.stream().map(CcCiClassInfo::getCiClass).collect(Collectors.toMap(CcCiClass::getClassName, e->e, (k1, k2) -> k1));
        //遍历所有制品
        List<EamArtifactElement> batchArtifact = new ArrayList<>();
        for (Map.Entry<Long, List<EamArtifactElementVo>> entry : columnsByIdsMap.entrySet()) {
            if (CollectionUtils.isEmpty(entry.getValue())) {
                continue;
            }
            //遍历每一个制品
            for (EamArtifactElementVo elementVo : entry.getValue()) {
                List<String> elements = elementVo.getElements();
                if (CollectionUtils.isEmpty(elements) || BinaryUtils.isEmpty(elementVo.getType()) || elementVo.getType() == 3 || elementVo.getType() == 4) {
                    continue;
                }
                //遍历每个制品的每个分栏
                List<String> newEle = new ArrayList<>();
                for (String element : elements) {
                    //这里如果是形状，不能转化成对象，形状存入的字段和架构元素不一致；
                    JSONObject jsonObject = JSON.parseObject(element);
                    if (BinaryUtils.isEmpty(jsonObject.get("name")) || !"class".equals(jsonObject.get("type"))) {
                        //形状
                        newEle.add(element);
                        continue;
                    }
                    EamArtifactVoCrush ciVo = JSON.parseObject(element, EamArtifactVoCrush.class);
                    String className = ciVo.getName();
                    CcCiClass ciClass = classMap.get(className);
                    if (BinaryUtils.isEmpty(ciClass)) {
                        continue;
                    }
                    ciVo.setId(ciClass.getId());
                    ciVo.setClassCode(ciClass.getClassCode());
                    String icon = ciVo.getIcon();
                    ciVo.setIcon(icon.replaceAll(rsmSlaveRoot, ""));
                    newEle.add(JSON.toJSONString(ciVo));
                }
                elementVo.setElements(newEle);
                EamArtifactElement ele = EamUtil.copy(elementVo, EamArtifactElement.class);
                batchArtifact.add(ele);
            }
        }
        columnSvc.saveOrUpdateBatch(batchArtifact);
        return "制品存量数据已更新";
    }

    @Override
    public String crushArtifactColumnsRelation() {
        BoolQueryBuilder query = new BoolQueryBuilder();
        query.must(QueryBuilders.termQuery("dataStatus",1));
        List<EamArtifact> queryScroll = eamArtifactDao.getListByQueryScroll(query);
        List<Long> idList = queryScroll.stream().map(EamArtifact::getId).collect(Collectors.toList());
        List<EamArtifactElement> batchArtifact = new ArrayList<>();
        for (Long id : idList) {
            //把type = 3 这栏全部清掉
            ElementDto elementDto = new ElementDto();
            elementDto.setArtifactId(id);
            elementDto.setType(3);
            List<EamArtifactElementVo> elementVos = columnSvc.queryAllColumns(elementDto);
            for (EamArtifactElementVo elementVo : elementVos) {
                elementVo.setElements(new ArrayList<>());
                EamArtifactElement element = EamUtil.copy(elementVo, EamArtifactElement.class);
                batchArtifact.add(element);
            }
        }
        columnSvc.saveOrUpdateBatch(batchArtifact);
        return null;
    }
    private static final String PRESET_QUERY_TYPE = "11";
    @Override
    public List<EamArtifactVo> queryArtifactByClass(List<EamArtifactVo> eamArtifactVoList, Map<String, String> param) {
        List<EamArtifactVo> result = new ArrayList<>();
        if (BinaryUtils.isEmpty(eamArtifactVoList) || BinaryUtils.isEmpty(param) || BinaryUtils.isEmpty(param.get("classId"))
                || param.get("queryType") == null || !param.get("queryType").equals(PRESET_QUERY_TYPE)) {
            return result;
        }
        // 架构资产类型
        List<Long> artifactIds = eamArtifactVoList.stream().map(EamArtifactVo::getId).collect(Collectors.toList());
        Map<Long, List<EamArtifactElement>> elementGroup = columnSvc.queryByIdsAndType(artifactIds, Collections.singletonList(ArtifactType.ASSET_TYPE.val()));
        for (EamArtifactVo artifactVo : eamArtifactVoList) {
            List<EamArtifactElement> elmentList = elementGroup.get(artifactVo.getId());
            if (BinaryUtils.isEmpty(elmentList)) {
                continue;
            }
            for (EamArtifactElement each : elmentList) {
                for (String element : each.getElements()) {
                    JSONObject elementJson = JSON.parseObject(element);
                    String id = elementJson.getString("id");
                    Boolean viewFlag = elementJson.getBoolean("viewFlag");
                    if (viewFlag && param.get("classId").equals(id)) {
                        result.add(artifactVo);
                        break;
                    }
                }
            }
        }
        return result;
    }


    @Override
    public String crushCreator() {
        BoolQueryBuilder query = new BoolQueryBuilder();
        query.must(QueryBuilders.termQuery("dataStatus",1));
        List<EamArtifact> queryScroll = eamArtifactDao.getListByQueryScroll(query);
        if(BinaryUtils.isEmpty(queryScroll)){
            return null;
        }
        for (EamArtifact artifact : queryScroll) {
            if(!BinaryUtils.isEmpty(artifact.getModifier()) && BinaryUtils.isEmpty(artifact.getCreator())){
                artifact.setCreator(artifact.getModifier());
            }
        }
        eamArtifactDao.saveOrUpdateBatch(queryScroll);
        return "creator字段刷新完成";
    }

    @Override
    public Map<String, Object> queryArtifactInfoById(Long artifactId) {
        Map<String, Object> result = new HashMap<>();
        EamArtifact artifact = eamArtifactDao.getById(artifactId);
        List<Long> fileIds = artifact.getFileIds();
        EamArtifactVo vo = new EamArtifactVo();
        BeanUtils.copyProperties(artifact,vo);
        if (!BinaryUtils.isEmpty(fileIds)) {
            Long fileId = fileIds.get(0);
            vo.setFileId(fileId);
            //只有一张图片
            FileResourceMeta fileResourceMeta = eamResourceSvc.download(fileIds).get(0);
            String picUrl = fileResourceMeta.getResPath();

            try {
                URL url = new URL(picUrl);
                URLConnection uc = url.openConnection();
                int code = ((HttpURLConnection) uc).getResponseCode();
                // 判断URL的状态，200表示成功 404 表示找不到
                if(code == 200){
                    vo.setResPath(fileResourceMeta.getResPath());
                }
                if(code == 404){
                    List<DefaultFileVo> defaultFileVos = defaultImage();
                    vo.setResPath(defaultFileVos.get(0).getResPath());
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        if(!BinaryUtils.isEmpty(vo)){
            result.put("artifact",vo);
        }
        ElementDto elementDto = new ElementDto();
        elementDto.setArtifactId(artifactId);
        List<EamArtifactElementVo> elements = columnSvc.queryAllColumns(elementDto);
        if(!BinaryUtils.isEmpty(elements)){
            //处理模板字段，多返回一个视图名称和icon
            List<EamArtifactElementVo> templateEle = elements.stream().filter(each -> each.getType() == 4).collect(Collectors.toList());
            if(!CollectionUtils.isEmpty(templateEle)){
                EamArtifactElementVo elementVo = templateEle.get(0);
                List<String> tempString = elementVo.getElements();
                List<ESDiagram> diagrams = columnSvc.queryTemplateByArtifactId(artifactId, 1, 3000, null).getData();
                if(!BinaryUtils.isEmpty(diagrams) && !BinaryUtils.isEmpty(tempString)){
                    List<String> newElements = new ArrayList<>();
                    Map<String, ESDiagram> diagramMap = diagrams.stream().collect(Collectors.toMap(ESDiagram::getDEnergy, each -> each, (k1, k2) -> k1));
                    for (String temp : tempString) {
                        JSONObject jsonObject = JSON.parseObject(temp);
                        String diagramId = jsonObject.get("diagramId").toString();
                        ESDiagram esDiagram = diagramMap.get(diagramId);
                        jsonObject.put("name",esDiagram.getName());
                        jsonObject.put("icon",esDiagram.getIcon1());
                        newElements.add(jsonObject.toJSONString());
                    }
                    elementVo.setElements(newElements);
                }
            }
            result.put("elements",elements);
        }
        return result;
    }

    @Override
    public List<Long> getArtifactClassIds(Long artifactId) {
        List<EamArtifactElementVo> elementVoList = columnSvc.queryByArtifactId(artifactId, Collections.singletonList(2));
        List<EamArtifactCiVo> elements = elementVoList.stream().map(EamArtifactElementVo::getElementCiObj).flatMap(Collection::stream).collect(Collectors.toList());
        List<Long> classIdList = new ArrayList<>();
        for (EamArtifactCiVo element : elements) {
            if ("class".equals(element.getType())) {
                classIdList.add(Long.valueOf(element.getId()));
            }
        }
        return classIdList;
    }

    @Override
    public List<DefaultFileVo> getImages() {
        List<DefaultFileVo> result = this.defaultImage();
        //查询上传的图片
        List<FileResourceMeta> uploadFile = eamResourceSvc.queryByType(1);
        List<DefaultFileVo> customList = new ArrayList<>();
        for (FileResourceMeta each : uploadFile) {
            DefaultFileVo vo = new DefaultFileVo();
            vo.setResPath(each.getResPath());
            vo.setFileId(each.getId());
            vo.setCreateTime(each.getCreateTime());
            if (!BinaryUtils.isEmpty(each.getName())) {
                vo.setImageName(each.getName().substring(0, each.getName().indexOf(".")));
            }
            customList.add(vo);
        }
        customList.sort(Comparator.comparing(DefaultFileVo::getCreateTime));
        result.addAll(customList);
        return result;
    }

    private Map<String, SysUser> queryUserMap(Collection<String> codes) {
        CSysUser cSysUser = new CSysUser();
        cSysUser.setLoginCodes(codes.toArray(new String[0]));
        cSysUser.setDomainId(SysUtil.getCurrentUserInfo().getDomainId());
        List<SysUser> userList = userApiSvc.getSysUserByCdt(cSysUser);
        Map<String, SysUser> userIdObjMap = new HashMap<>(userList.size());
        for (SysUser user : userList) {
            user.setLoginPasswd(null);
            String icon = user.getIcon();
            if (icon != null && !icon.startsWith(rsmSlaveRoot)) {
                user.setIcon(rsmSlaveRoot + icon);
            }
            userIdObjMap.put(user.getLoginCode(), user);
        }
        return userIdObjMap;
    }

    @Override
    public List<EamArtifact> queryReleaseList(List<Integer> type) {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.termQuery("dataStatus", 1));
        boolQueryBuilder.must(QueryBuilders.termQuery("releaseState", 1));
        if (!BinaryUtils.isEmpty(type)) {
            boolQueryBuilder.must(QueryBuilders.termsQuery("typeClassification", type));
        }
        List<EamArtifact> artifactList = eamArtifactDao.getListByQuery(boolQueryBuilder);
        if(BinaryUtils.isEmpty(artifactList)){
            return Collections.emptyList();
        }
        return artifactList;
    }

    @Override
    public List<EamArtifact> queryArtifactSimpleInfo(List<Long> artifactIds) {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.termsQuery("id", artifactIds));
        return eamArtifactDao.getListByQuery(boolQueryBuilder);
    }
}
